package com.zhuss.core.processor;

import java.util.Date;
import java.util.List;
import java.util.Set;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import com.zhuss.bean.bo.core.login.LogoutBo;
import com.zhuss.bean.bo.core.login.TokenBo;
import com.zhuss.bean.bo.core.user.wechat.UnbindUserOpenIdBo;
import com.zhuss.bean.vo.core.user.DetailUserVo;
import com.zhuss.common.AbstractProcessor;
import com.zhuss.common.Processor;
import com.zhuss.core.db.dao.ext.UserDao;
import com.zhuss.core.db.entity.User;
import com.zhuss.db.entity.OpLog;
import com.zhuss.enums.LogActionEnum;
import com.zhuss.enums.MoudleEnum;
import com.zhuss.enums.SystemEnum;
import com.zhuss.exception.OceanException;
import com.zhuss.util.JsonUtil;

/**
 * 登出 processor
 * @Author: zhushanshuo
 * @Date: 2019/9/24 19:54
 */
@Component("logoutProcessor")
public class LogoutProcessor extends AbstractProcessor<Object, LogoutBo> implements Processor<Object, LogoutBo> {
	
	@Autowired
	@Qualifier("userRead")
	private UserRead userRead;
	
	@Autowired
	private UserDao userDao;
    
	@Autowired
	@Qualifier("logoutRedis")
	private Processor<Void, TokenBo> logoutRedis;
	
	@Autowired
	@Qualifier("userOpenIdUnbind")
	private Processor<Object, UnbindUserOpenIdBo> userOpenIdUnbind;
	
	@Autowired
	@Qualifier("loginRedis")
	private Processor<Void, TokenBo> loginRedis;
	
    /**
     * 校验
     */
    @Override
    public void check(LogoutBo bo) throws OceanException {
    }
    
    /**
     * 操作方法
     * @throws OceanException 
     */
    @Override
    public Object process(LogoutBo bo) throws OceanException {
    	User record = new User();
    	Long userId = bo.getConcurrentUserId();
    	bo.setTargetId(record.getUserId());
    	
    	// 小程序 把 后台用户的user的openId清空， 即当前后台用户没有了游客绑定
    	if (SystemEnum.小程序.sameKey(bo.getConcurrentSystem())) {
    		String openId = bo.getConcurrentToken();
    		UnbindUserOpenIdBo unbindUserOpenIdBo = new UnbindUserOpenIdBo();
    		BeanUtils.copyProperties(bo, unbindUserOpenIdBo);
    		unbindUserOpenIdBo.setUserId(userId);
    		unbindUserOpenIdBo.setOpenId(openId);
    		userOpenIdUnbind.process(unbindUserOpenIdBo);
    	}
    	
    	// redis 用户， 当前openId（token） 对应的清除
    	TokenBo param = new TokenBo();
    	BeanUtils.copyProperties(bo, param);
    	param.setToken(bo.getConcurrentToken());
    	param.setUserId(bo.getConcurrentUserId());
    	logoutRedis.process(param);
    	
    	// 游客ID绑定redis
    	if (SystemEnum.小程序.sameKey(bo.getConcurrentSystem())) {
    		String openId = bo.getConcurrentToken();
    		List<User> userList = userRead.listByOpenId(openId);
    		User user = userList.get(0);
    		TokenBo paramToken = new TokenBo();
        	BeanUtils.copyProperties(bo, paramToken);
        	paramToken.setToken(openId);
        	paramToken.setUserId(user.getUserId());
        	loginRedis.process(paramToken);
    	}
    	
    	
    	// app 退出登录解绑cid
    	String cid = bo.getCid();
    	if (cid != null && !"".equals(cid)) {
    		DetailUserVo userDb = (DetailUserVo) userRead.detail(userId);
    		Set<String> cidDb = userDb.getCid();
    		cidDb.remove(cid);
    		StringBuffer sb = new StringBuffer();
    		if (cidDb != null && cidDb.size() > 0) {
    			for (String str : cidDb) {
    				sb.append(str);
    				sb.append(",");
    			}
    			sb.deleteCharAt(sb.lastIndexOf(","));
    		}
    		String cidListStr = sb.toString();
    		User updateRecord = new User();
    		updateRecord.setUserId(userId);
    		updateRecord.setCid(cidListStr);
    		userDao.updateByPrimaryKeySelective(updateRecord);
    	}
    	
        return null;
    }
    
    /**
     * 操作日志
     */
	@Override
	public Object log(LogoutBo param) throws OceanException {
		OpLog record = new OpLog();
    	record.setMoudle(MoudleEnum.基础模块.key());
    	record.setAction(LogActionEnum.登出.key());
    	record.setTargetId(param.getTargetId());
    	record.setTargetName(null);
    	record.setContent("参数: " + JsonUtil.toJson(param));
    	record.setReason(param.getExceptionReason());
    	
    	record.setCreatorId(param.getConcurrentUserId());
    	record.setCreator(param.getConcurrentUserName());
    	record.setCreateTime(new Date());
    	log(record);
    	return null;
	}
}
